mod instruction;
mod bytecode_reader;

pub use instruction::Instruction;
pub use bytecode_reader::BytecodeReader;

use std::{rc::Rc, cell::RefCell, sync::{Arc, Mutex}};
use crate::rtda::{Frame, heap::{Method, Class, self}, self, OperandStack, Thread, LocalVars, Object};

// 跳转到指定位置，例如下一次循环
pub fn branch(frame: Rc<RefCell<Frame>>, offset: i32) {
    let mut frame = frame.borrow_mut();
    let pc = frame.get_thread().lock().unwrap().get_pc();
    let next_pc = pc + offset;
    frame.set_next_pc(next_pc as usize);
}

// 执行方法
pub fn invoke_method(invoker_frame: Rc<RefCell<Frame>>, method: Arc<Method>) {
    let stack = invoker_frame.borrow().get_operand_stack();
    let thread = invoker_frame.borrow().get_thread();
    // 创建新帧
    let new_frame = Frame::new_frame(thread.clone(), method.clone());
    // 传递参数
    let mut arg_slot_slot = method.get_arg_slot_count();
    while arg_slot_slot > 0 {
        arg_slot_slot -= 1;
        let slot = stack.borrow_mut().pop_slot();
        new_frame.get_local_vars().borrow_mut().set_slot(arg_slot_slot, slot);
    }

    // 添加frame放到最后
    thread.lock().unwrap().push_frame(new_frame);
}

// 执行java方法，获取返回结果
pub fn invoke_java_method(method: Arc<Method>, vars: LocalVars, caller_class: Option<Arc<Class>>, j_thread: Option<*mut Object>) -> Rc<RefCell<OperandStack>> {
    let stack = Rc::new(RefCell::new(OperandStack::new_operand_stack(2)));
    let caller_class = match caller_class {
        Some(class) => class,
        None => Arc::new(Class::new_shim())
    };

    let thread = Arc::new(Mutex::new(Thread::new_shim_thread(j_thread)));
    // 新建frame用来接收返回结果，通过指定类以防止一些native无法获取到当前类（例如Reflection.getCallerClass）
    let _frame = Frame::new_shim_frame_specify_class(thread.clone(), stack.clone(), caller_class);
    // 创建新帧，执行java方法
    let invoker_frame = Frame::new_frame1(thread.clone(), method, vars);
    thread.lock().unwrap().push_frame(_frame);
    thread.lock().unwrap().push_frame(invoker_frame);

    // 执行
    crate::interpreter::_loop(thread.clone(), false);

    stack
}
pub fn invoke_java_method_log(method: Arc<Method>, vars: LocalVars, caller_class: Option<Arc<Class>>, j_thread: Option<*mut Object>) -> Rc<RefCell<OperandStack>> {
    let stack = Rc::new(RefCell::new(OperandStack::new_operand_stack(2)));
    let caller_class = match caller_class {
        Some(class) => class,
        None => Arc::new(Class::new_shim())
    };

    let thread = Arc::new(Mutex::new(Thread::new_shim_thread(j_thread)));
    // 新建frame用来接收返回结果，通过指定类以防止一些native无法获取到当前类（例如Reflection.getCallerClass）
    let _frame = Frame::new_shim_frame_specify_class(thread.clone(), stack.clone(), caller_class);
    // 创建新帧，执行java方法
    let invoker_frame = Frame::new_frame1(thread.clone(), method, vars);
    thread.lock().unwrap().push_frame(_frame);
    thread.lock().unwrap().push_frame(invoker_frame);

    // 执行
    crate::interpreter::_loop(thread.clone(), true);

    stack
}


// 初始化class
pub fn init_class(thread: Arc<Mutex<rtda::Thread>>, class: Arc<Class>) {
    // 231028 Class unsafe 通过加锁仅允许一个线程进行初始化，是安全的。
    unsafe {
        class.strat_init();
    }
    schedule_clinit(thread.clone(), &class);
    init_super_class(thread, &class);
}

// 准备执行初始化方法
fn schedule_clinit(thread: Arc<Mutex<rtda::Thread>>, class: &heap::Class) {
    // get_clinit_method 查找了所有层级的clinit ，此时支取本层级的。
    if let Some(clinit) = class.get_clinit_method() {
        // exec <clinit>
        if std::ptr::eq(clinit.get_class().as_ref(), class)  {
            let new_frame = Frame::new_frame(thread.clone(), clinit);
            // println!("new_className:{}", class.get_name());
            // println!("new_frame: {}", new_frame);
            thread.lock().unwrap().push_frame(new_frame);
        }
    }
}

// 初始化父类，保证父类先于子类初始化
fn init_super_class(thread: Arc<Mutex<rtda::Thread>>, class: &heap::Class) {
    // print!("className:{}", class.get_name());
    if !class.is_interface() {
        if let Some(super_class) = class.get_super_class() {
            if !super_class.init_started() {
                init_class(thread, super_class);
            }
        }
    }
}